/* QtLua -- Lua bindings for Qt
   Copyright (C) 2011, Jarek Pelczar

   This library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Lesser General Public
   License as published by the Free Software Foundation; either
   version 3 of the License, or (at your option) any later version.

   This library is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General
   Public License along with this library; if not, write to the
   Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
   Boston, MA 02110-1301 USA

*/

#include "qluaengineglobals_p.h"
#include "qluascriptvalue.h"
#include "qluaglobal.h"
#include "qluametaobjectwrapper_p.h"
#include "qluaexposedproperty_p.h"
#include "qluascriptconsoleinterface_p.h"
#include "qluaqobjectwrapper_p.h"

Q_GLOBAL_STATIC(QLuaEngineGlobals, lua_engine_globals)

QLuaEngineGlobals * QLuaEngineGlobals::get()
{
    return lua_engine_globals();
}

QLuaEngineGlobals::QLuaEngineGlobals()
{
    qRegisterMetaType<QLuaScriptValue>("QLuaScriptValue");
    qRegisterMetaType<QLuaInternal::QLuaMetaObjectWrapper>("QLuaInternal::QLuaMetaObjectWrapper");
    qRegisterMetaType<QLuaInternal::QLuaExposedProperty>("QLuaInternal::QLuaExposedProperty");
    qRegisterMetaType<QLuaInternal::QLuaMetaPropertyWrapper>("QLuaInternal::QLuaMetaPropertyWrapper");
    qRegisterMetaType<QLuaInternal::QLuaQObjectWrapper>("QLuaInternal::QLuaQObjectWrapper");
    qRegisterMetaType<QLuaInternal::QLuaMetaMethodWrapper>("QLuaInternal::QLuaMetaMethodWrapper");
}

void QLuaEngineGlobals::registerEngine(lua_State * L, QLuaScriptEngine * engine, QLuaScriptEnginePrivate * d)
{
    QLuaEngineGlobals * g = lua_engine_globals();
    QMutexLocker locker(&g->m_lock);
    g->m_stateToEngine.insert(L, engine);
    g->m_stateToEngineImpl.insert(L, d);
}

void QLuaEngineGlobals::unregisterEngine(lua_State * L)
{
    QLuaEngineGlobals * g = lua_engine_globals();
    QMutexLocker locker(&g->m_lock);
    g->m_stateToEngine.remove(L);
    g->m_stateToEngineImpl.remove(L);
}

void QLuaEngineGlobals::registerQObject(QObject * o, QLuaScriptEngine * engine)
{
    QLuaEngineGlobals * g = lua_engine_globals();
    QObject::connect(o, SIGNAL(destroyed(QObject*)), g, SLOT(object_destroyed(QObject*)));
    QMutexLocker locker(&g->m_lock);
    g->m_objectToEngine.insert(o, engine);
}

void QLuaEngineGlobals::object_destroyed(QObject * o)
{
    QMutexLocker locker(&m_lock);
    m_objectToEngine.remove(o);
}

QLuaScriptEngine * QLuaEngineGlobals::engineFromQObject(QObject * o)
{
    QLuaEngineGlobals * g = lua_engine_globals();
    QMutexLocker locker(&g->m_lock);
    return g->m_objectToEngine.value(o, NULL);
}

QLuaScriptEngine * qluaEngine(QObject * o)
{
    return QLuaEngineGlobals::engineFromQObject(o);
}

QLuaScriptEngine * QLuaEngineGlobals::engineFromLua(lua_State * L)
{
    QLuaEngineGlobals * g = lua_engine_globals();
    QMutexLocker locker(&g->m_lock);
    return g->m_stateToEngine.value(L, NULL);
}

void QLuaEngineGlobals::registerDebuggerConsole(QLuaScriptConsoleInterface * I)
{
    QLuaEngineGlobals * g = lua_engine_globals();
    QMutexLocker locker(&g->m_lock);
    g->m_debuggerConsoles.insert(QLuaScriptEnginePrivate::priv(I->engine())->L, I);
}

void QLuaEngineGlobals::unregisterDebuggerConsole(QLuaScriptConsoleInterface * I)
{
    QLuaEngineGlobals * g = lua_engine_globals();
    QMutexLocker locker(&g->m_lock);
    lua_State * L = g->m_debuggerConsoles.key(I);
    g->m_debuggerConsoles.remove(L);
}

QLuaScriptConsoleInterface * QLuaEngineGlobals::debuggerConsole(lua_State * L)
{
    QLuaEngineGlobals * g = lua_engine_globals();
    QMutexLocker locker(&g->m_lock);
    return g->m_debuggerConsoles.value(L);
}
